/*
 * flock.h
 *
 *  Created on: 15.02.2012
 *      Author: ignacio
 */

#ifndef FLOCK_H_
#define FLOCK_H_

#include "steering.h"
#include "Gluon.h"

namespace neurignacio{

enum GroupSteeringBehaviour_ID{GROUP_STEERING_NONE=100, FLOCK};

class CharacterPointerContainer
// Contains the references to the character group
{
public:
	GluonPointerContainer characterContainer;
public:
	CharacterPointerContainer() : characterContainer() {}
	CharacterPointerContainer(GluonPointerContainer& characterContainer) : characterContainer(characterContainer) {}
	void setCharacter(GluonPointerContainer* character) {characterContainer=*character;}
};

template <typename Type>
class TargetPointerContainer
// Contains the references to the Type used as targets
{
public:
	BasePointerContainer<Type> targetContainer; // Pointer or Value?????????????????????????????????????????????
public:
	TargetPointerContainer() {}
	TargetPointerContainer(BasePointerContainer<Type> targetContainer) : targetContainer(targetContainer) {}
	void setTarget(BasePointerContainer<Type>* target) {targetContainer=target;}
};
class TargetLocationPointerContainer : public TargetPointerContainer<Location>
{
//  protected: BaseContainer<Location*> *targetContainer [=LocationContainer]
};

class TargetLeptonPointerContainer : public TargetPointerContainer<Lepton>
// Contains the references to the leptons used as targets
{
//  protected: BasePointerContainer<Lepton> *targetContainer [=LeptonPointerContainer]
public:
	TargetLeptonPointerContainer() {}
	TargetLeptonPointerContainer(LeptonPointerContainer* group) {targetContainer=*group;}
	Vector3 averagePosition() const;
	Vector3 averageVelocity() const;
};
/*
class DependentBehaviour
// Dependent Behaviour stores all the behaviours that are affected by the parent behaviour
// z.B. flock calculates a target according to a group and set it to all the dependent behaviours.
{
public:
	MovementBehaviourPointerContainer* movementBehaviour;
};
*/

class Flock : public SteeringBehaviour, public CharacterPointerContainer
{
protected:
	virtual void init() {MovementBehaviour_ID=FLOCK; MovementBehaviour_Description="FLOCK";}

// Predefined Behaviours in controlling boids in Flock
public:
	CollisionAvoidance collision;
	Arrive arrive;
	Look look;

public:
	real horizont; 		// = neighbourhood distance (only "boids" within the horizont will affect the behaviour of one particular boid)
	angle fieldOfView; 	// extent of the observable world that is affects the behaviour of one particular boid.
public:
	Flock() : SteeringBehaviour(), horizont(REAL_MAX), fieldOfView(TWO_PI_ANGLE) {init();}
	void getSteering(SteeringOutput& output);
};

} // end namespace neurignacio
#endif /* FLOCK_H_ */
